
#include <string>
#include <list>

#include "util.hxx"
#include "module.hxx"
#include "minilog_static.hxx"
using std::string;
using std::list;

#ifdef __cplusplus
extern "C" {
#endif
#include <string.h>
#include <stdio.h>
#ifdef __cplusplus
}
#endif

TestModule::TestModule(void)
{
    m_defaultTestResult = 1;
    m_enable = 1;
    m_automation = 1;
    m_runResult = m_defaultTestResult;
    resetAttr();
}

void TestModule::resetAttr(void)
{
    f_preInit = nullptr;
    f_init = nullptr;
    f_run  = nullptr;
    f_quit = nullptr;
    f_pendingData = nullptr;
    f_action_notify = nullptr;
    preInitFlag = 0;
    initFlag = 0;
}

void TestModule::setName(const string &name)
{
    m_name = name;
}

string &TestModule::getName(void)
{
    return m_name;
}

void TestModule::setOwner(class TestModulesManager*owner)
{
    m_owner = owner;
}

class TestModulesManager*TestModule::getOwner(void)
{
    return m_owner;
}

TestModule::TestModule(const string &name,
                       enum TestResult defaultResult,
                       enum ModuleEnable moduleEnable,
                       enum ModuleAutoEnable autoEnable)
{
    setName(name);
    setDefaultTestResult(defaultResult);
    setEnable(moduleEnable);
    setAutomation(autoEnable);
    resetAttr();
}

/* 设置属性 */
void TestModule::setDefaultTestResult(enum TestResult result)
{
    m_defaultTestResult = result;
}
bool TestModule::getDefaultTestResult(void)
{
    return m_defaultTestResult;
}

void TestModule::setEnable(enum ModuleEnable enable)
{
    m_enable = enable;
}
bool TestModule::getEnable(void)
{
    return m_enable;
}

void TestModule::setAutomation(enum ModuleAutoEnable enable)
{
    m_automation = enable;
}
bool TestModule::getAutomation(void)
{
    return m_automation;
}

void TestModule::setAttrs(enum TestResult defaultResult,
                          enum ModuleEnable moduleEnable,
                          enum ModuleAutoEnable autoEnable)
{
    setDefaultTestResult(defaultResult);
    setEnable(moduleEnable);
    setAutomation(autoEnable);
}

/* 设置方法 */
#if 0
// 这个方法是必要的吗
void* TestModule::getActionArg(void)
{
    return m_arg;
}
#endif

void TestModule::setActionArg(void *arg)
{
    m_arg = arg;
}

void TestModule::setRuntimeArg(struct moduleRuntimeArg * runtimeArg)
{
    struct moduleActionArg res;

    runtimeArg = runtimeArg;
    if(f_action_notify)
    {
        res.runtimeArg = runtimeArg;
        f_action_notify(ModuleActionSetRuntimeArg, &res);
    }
}
struct moduleRuntimeArg* TestModule::newRuntimeArgFromRequest(struct moduleRequest* request)
{
    struct moduleRuntimeArg * runtimeArg = nullptr;
    if(!request || request->dataSize == 0)
    {
        return nullptr;
    }

    runtimeArg = new struct moduleRuntimeArg;
    runtimeArg->size = min(request->dataSize, MODULE_DATA_MAX_SIZE);
    memcpy(runtimeArg->data, request->data, runtimeArg->size);
    return runtimeArg;
}

void TestModule::setPreInit(void (*func)(void*))
{
    f_preInit = func;
}
void TestModule::setInit(bool (*func)(void*))
{
    f_init = func;
}
void TestModule::setRun(bool (*func)(void*))
{
    f_run = func;
}
void TestModule::setQuit(void (*func)(void*))
{
    f_quit = func;
}
void TestModule::setPendingStr(char* (*func)(void*))
{
    f_pendingData = func;
}
void TestModule::setActions(void (*preInit)(void*),
                            bool (*init)(void*),
                            bool (*run)(void*),
                            void (*quit)(void*),
                            char*(*pendingStr)(void*),
                            void (*action_notify)(int, void*))
{
    f_preInit       = preInit;
    f_init          = init;
    f_run           = run;
    f_quit          = quit;
    f_pendingData    = pendingStr;
    f_action_notify = action_notify;
}

void TestModule::preInit(void)
{
    if(f_preInit) f_preInit(m_arg);
    if(f_action_notify) f_action_notify(ModuleActionPreinit, nullptr);
}

bool TestModule::init(void)
{
    if(f_init) f_init(m_arg);
    if(f_action_notify) f_action_notify(ModuleActionInit, nullptr);

    return 0;
}

bool TestModule::run(void)
{
    m_runResult = (f_run) ? f_run(m_arg) : m_defaultTestResult;
    if(f_action_notify) f_action_notify(ModuleActionRun, nullptr);
    return m_runResult;
}

void TestModule::quit(void)
{
    if(f_quit) f_quit(m_arg);
    if(f_action_notify) f_action_notify(ModuleActionQuit, nullptr);
}

bool TestModule::getRunResult(void)
{
    if(f_action_notify) f_action_notify(ModuleActionGetRunResult, nullptr);
    return m_runResult;
}

void TestModule::setRunResult(bool result)
{
    struct moduleActionArg res;

    m_runResult = result;

    if(f_action_notify)
    {
        res.setRunResult = result;
        f_action_notify(ModuleActionSetRunResult, &res);
    }
}

char * TestModule::getPendingData(void)
{
    if(f_pendingData)
    {
        return f_pendingData(m_arg);
    }
    return nullptr;
}
